package impl

import (
	"context"
	"time"

	"gitee.com/yangwencheng/vblog/apps/user"
	"gitee.com/yangwencheng/vblog/common"
	"gorm.io/gorm"
)

// 查询列表
func (impl *Impl) QueryUser(ctx context.Context, in *user.QueryUserRequest) (*user.UserSet, error) {

	query := impl.db.Session(&gorm.Session{}).WithContext(ctx)
	if in.ID != 0 {
		query = query.Where("id = ?", in.ID)
	}
	if in.Username != "" {
		query = query.Where("username = ?", in.Username)
	}

	userSet := user.NewUserSet()
	result := query.Model(&user.User{}).Count(&in.Total).Scopes(common.Paginate(in.PageData)).Find(&userSet.Items)
	userSet.PageData = in.PageData
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}

	return userSet, nil
}

// 创建
func (impl *Impl) CreateUser(ctx context.Context, in *user.CreateUserRequest) (*user.User, error) {
	err := in.Validate()
	if err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	user := user.NewUser()
	user.CreateUserRequest = in
	// 生成并且覆盖加密字符串
	if err := user.GeneratePassword(); err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	result := impl.db.Create(user)
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}
	return user, nil
}

// 更新
func (impl *Impl) UpdateUser(ctx context.Context, cbr *user.CreateUserRequest, user *user.User) (*user.User, error) {
	err := cbr.Validate()
	if err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	result := impl.db.First(user)
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}
	user.CreateUserRequest = cbr
	user.UpdatedAt = time.Now().Unix()
	result = impl.db.Save(user)
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}
	return user, nil
}

// 删除
func (impl *Impl) DeleteUser(cxt context.Context, delUserReq *user.DeleteUserRequest) (*user.User, error) {

	if err := delUserReq.Validate(); err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	user := user.NewUser()
	user.ID = delUserReq.ID
	result := impl.db.Delete(user)
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}
	if result.RowsAffected == 0 {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, "数据不存在")
	}
	return user, nil
}

// 详情
func (impl *Impl) ShowUser(ctx context.Context, showUserReq *user.ShowUserRequest) (*user.User, error) {

	if err := showUserReq.Validate(); err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	user := user.NewUser()
	user.ID = showUserReq.ID
	result := impl.db.First(user)
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}
	return user, nil
}

// 用户登录
func (impl *Impl) Login(ctx context.Context, in *user.LoginUserRequest) (*user.Token, error) {

	if err := in.Validate(); err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	baseQuery := impl.db.Session(&gorm.Session{}).WithContext(ctx)

	query := baseQuery.Where("username = ?", in.Username)
	u := user.NewUser()
	result := query.First(u)
	if result.Error != nil {
		return nil, common.NewApiException(common.DATABASE_ERROR_CODE, result.Error.Error())
	}
	// 检查密码
	if err := u.CheckPassword(in.Password); err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, "用户名或者密码不正确")
	}
	// 更新或者生成token
	tk := user.NewToken()
	tk.Username = in.Username
	tokenQuery := baseQuery.Where("username = ?", in.Username)
	tokenQuery.Find(tk)
	tk.GenerateToken()
	result = baseQuery.Save(tk)
	if result.Error != nil {
		return nil, result.Error
	}
	return tk, nil
}

// 验证token
func (impl *Impl) ValidateToken(ctx context.Context, in *user.ValidateTokenRequest) (*user.User, error) {
	if err := in.Validate(); err != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, err.Error())
	}
	// 查询一下token
	baseQuery := impl.db.Session(&gorm.Session{}).WithContext(ctx)
	tk := user.NewToken()
	result := baseQuery.Where("access_token = ?", in.AccessToken).First(tk)
	if result.Error != nil {
		return nil, common.NewApiException(common.PARAMS_ERROR_CODE, "token参数错误")
	}
	if err := tk.CheckExpire(); err != nil {
		return nil, err
	}
	// 查询用户
	u := user.NewUser()
	result = baseQuery.Where("username = ?", tk.Username).First(u)
	if result.Error != nil {
		return nil, result.Error
	}
	return u, nil
}
